#include "task.h"
#include "user.h"
#include <vector>
#include <string>
#include <iostream>
#include <ctime>
#include <iomanip>
#include <chrono>
#include <sstream>
#include <thread>
#include <atomic>
#include <fstream>
#include <unordered_map>
#include <cctype>
#include <mutex>
#include <condition_variable>
#include <algorithm>
using namespace std;

// 共享数据结构和同步机制
struct SharedData {
    vector<task> tasks;
    string order;
    bool logoutRequested = false;
    bool dataUpdated = false;
    mutex mtx;
    condition_variable cv;
};

string getCurrentTimeString() {
    auto now = chrono::system_clock::now();
    time_t now_time = chrono::system_clock::to_time_t(now);
    tm* local_time = localtime(&now_time);
    
    ostringstream oss;
    oss << setfill('0') 
        << setw(4) << local_time->tm_year + 1900
        << setw(2) << local_time->tm_mon + 1
        << setw(2) << local_time->tm_mday
        << setw(2) << local_time->tm_hour
        << setw(2) << local_time->tm_min;
    
    return oss.str();
}

void backcheck(SharedData& sharedData) {
    while (true) {
        // 等待主线程通知或超时
        unique_lock<mutex> lock(sharedData.mtx);
        sharedData.cv.wait_for(lock, chrono::seconds(10), [&] {
            return sharedData.dataUpdated || sharedData.logoutRequested;
        });
        
        if (sharedData.logoutRequested) {
            break;
        }
        
        // 检查任务状态
        string time = getCurrentTimeString();
        vector<string> tasksToRemove;
        
        for (const auto& t : sharedData.tasks) {
            if (t.start_time > time && t.notice_time <= time) {
                cerr << t.name << " will start soon" << endl;
            }
            if (t.start_time <= time) {
                cerr << t.name << " has started" << endl;
                tasksToRemove.push_back(t.id);
            }
        }
        
        // 移除已完成的任务
        for (const auto& id : tasksToRemove) {
            auto it = find_if(sharedData.tasks.begin(), sharedData.tasks.end(),
                [&](const task& t) { return t.id == id; });
                
            if (it != sharedData.tasks.end()) {
                sharedData.tasks.erase(it);
            }
        }
        
        sharedData.dataUpdated = false;
    }
}

int main() {
    setbuf(stdout, nullptr);
    setbuf(stderr, nullptr);
    
    AccountManager manager;
    string command;
    cin >> command;
    if(command == "help") {
        cout << "help: please input run to start the program"<<endl;
    }
    else if(command == "run") {
        while(true) {
            cout << "system\n";
            cout << "command: register, login, exit\n";
            string username, password;
            
            while (true) {
                cout << "> ";
                cin >> command;

                if (command == "register") {
                    cout << "register" << endl;
                    cout << "username: " << endl;
                    cin >> username;
                    cout << "password: " << endl;
                    cin >> password;
                    bool flag = manager.registerUser(username, password);
                    if(flag) {
                        ofstream file(username);
                        file.close();
                        break;
                    }
                } else if (command == "login") {
                    cout << "login" << endl;
                    cout << "username: " << endl;
                    cin >> username;
                    cout << "password: " << endl;
                    cin >> password;
                    bool flag = manager.login(username, password);
                    if(flag) break;
                } else if (command == "exit") {
                    return 0;
                } else {
                    cout << "unkonwn command\n";
                }
            }
            
            ifstream file(username);
            if(!file) {
                cout << "error:have wrong in operating the file" << endl;
                return 0;
            }
            
            // 创建共享数据结构
            SharedData sharedData;
            
            string name;
            cout << "initializing" << endl;
            while(file >> name) {
                string start_time, notice_time, level, element;
                file >> start_time >> notice_time >> level >> element;
                task t(name, start_time, notice_time, level, element);
                
                lock_guard<mutex> lock(sharedData.mtx);
                sharedData.tasks.push_back(t);
            }
            cout << "finished" << endl;
            file.close();
            
            // 启动后台线程
            thread backcheckThread(backcheck, ref(sharedData));
            
            while(true) {
                cout << username << "> ";
                cin >> sharedData.order;
                
                // 处理命令
                {
                    lock_guard<mutex> lock(sharedData.mtx);
                    
                    if (sharedData.order == "showtasks") {
                        string model = "day";
			if (cin.peek() != '\n') {
                            cin >> model;
                        } else {
                            cin.ignore();
                        }
			cout<<"showtasks"<<" "<<model<<endl;
                        showtasks(sharedData.tasks, model);
			cerr << "success\n";
                    }
                    else if(sharedData.order == "addtask") {
                        string a, b, c, d = "1", e = "entertainment";
                        cin >> a >> b >> c;
                        if (cin.peek() != '\n') {
                            cin >> d;
                            if (cin.peek() != '\n') {
                                cin >> e;
                            }
                        }
			string time = getCurrentTimeString();
                        bool flag=true;
			if(b<=c||b<=time){
			flag=false;
			cerr<<"your input time have an error"<<endl;
			}
			if(flag){
                        addtask(sharedData.tasks, a, b, c, d, e);
                        sharedData.dataUpdated = true;
			cout<<"addtask"<<" "<<a<<" "<<b<<" "<<c<<" "<<d<<" "<<e<<endl;
			cerr<<"success"<<endl;
			}
                    }
                    else if(sharedData.order == "deltask") {
                        string id;
                        cin >> id;
			bool flag=false;
			for(const auto&t : sharedData.tasks){
			if(t.id==id){
			flag=true;
			cerr<<"the task does not exist"<<endl;
	                break;		
			}
			}
			if(flag){
                        deltask(sharedData.tasks, id);
                        sharedData.dataUpdated = true;
			cout<<"deltask"<<" "<<id<<endl;
			cerr<<"success"<<endl;
			}
                    }
                    else if(sharedData.order == "help") {
                        cerr << "usable commands: showtasks, addtask, deltask, help, logout, save\n";
                        cerr << "showtasks: show tasks, you can input day or month or all  to show tasks by day or month or all\n";
                        cerr << "addtask: add a new task, you must input name, start_time, notice_time, level, element (level and element are optional)\n";
			cerr << "for example ,the form of time must be year+month+hour+minute,if today is 2025.7.11.15.47,you habe to input 202507111547\n";
                        cerr << "deltask: delete a task, you can input the id of the task\n";
                        cerr << "help: show help\n";
                        cerr << "logout: logout and save tasks\n";
                        cerr << "save: save tasks to file\n";
			cerr << "you can either use button or input your command to use this program\n";
                    }
                    else if(sharedData.order == "logout") {
                        ofstream out(username);
                        for(const auto& t : sharedData.tasks) {
                            out << t.name << " " << t.start_time << " " 
                                << t.notice_time << " " << t.level << " " 
                                << t.element << endl;
                        }
                        out.close();
                        
                        // 通知线程退出
                        sharedData.logoutRequested = true;
                        break;
                    }
                    else if(sharedData.order == "save") {
                        ofstream out(username);
                        for(const auto& t : sharedData.tasks) {
                            out << t.name << " " << t.start_time << " " 
                                << t.notice_time << " " << t.level << " " 
                                << t.element << endl;
                        }
                        out.close();
			cout<<"save"<<endl;
			cerr<<"success"<<endl;
                    }
                }
                
                // 通知后台线程检查更新
                if (sharedData.dataUpdated) {
                    sharedData.cv.notify_one();
                }
            }
            
            // 等待后台线程结束
            backcheckThread.join();
        }
    }
    return 0;
}
